<?php

namespace App\Listeners\OpenShop;

use App\Enums\OpenShop\InvestmentPromotion\SiteMissionEnum;
use App\Enums\OpenShop\MissionTemplateEnum;
use App\Events\OpenShop\SystemNotifyCenterEvent;
use App\Library\Common\Push\KfPushFactory;
use App\Listeners\BaseListener;
use App\Models\Common\CommonPushBindModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSiteMissionModel;
use App\Models\System\SystemNotifyCenterModel;
use App\Service\OpenShop\Feishu\MissionTemplateService;
use App\Service\OpenShop\Feishu\SiteMissionService;
use App\Service\OpenShop\OrderService;
use App\Service\System\SystemNotifyService;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Kuafu\AppPush\PushParam;

class SystemNotifyPushListener extends BaseListener
{
    public ?array $pushRmsUserIds   = null;
    public array  $pushedRmsUserIds = [];

    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }


    /**
     * Handle the event.
     *
     * @param SystemNotifyCenterEvent $event
     */
    public function handle(SystemNotifyCenterEvent $event)
    {
        // 判断是否需要发极光推送
        $notifyModel = $event->notifyCenterModel;

        if (empty($notifyModel->pushTitle)) {
            return;
        }

        // 判断是否预推送
        if (!empty($event->prePushTargetList)) {
            $this->pushRmsUserIds = $event->prePushTargetList;
            $pushParam            = (new PushParam())
                ->setMessage($notifyModel->pushTitle)
                ->setRmsDomain(rtrim(config('rms.domain'), '/'));
        } else {
            $pushParam = (new PushParam())
                ->setMessage($notifyModel->pushTitle)
                ->setRmsDomain(rtrim(config('rms.domain'), '/'));

            $userList             = SystemNotifyService::getTargetUserList($notifyModel);
            $idList               = array_column($userList, 'id');
            $this->pushRmsUserIds = $idList;
        }

        SystemNotifyService::recordLog($notifyModel, '手机系统 消息推送中');

        //接驳各自手机各自厂商的推送
        $this->mobileBrandChannelPush($notifyModel);

        //极光推送
        $this->jPush($pushParam, $notifyModel);

        // 所有推送结束，更新标记
        if (empty($event->prePushTargetList)) {

            $tempLoop = $this->queueLoop;

            dispatch(function () use ($notifyModel, $tempLoop) {

                Log::info("appPush dispatch {$tempLoop} finish");

                $notifyModel->status = SystemNotifyCenterModel::NOTIFY_STATUS_3;
                $notifyModel->save();

                SystemNotifyService::recordLog($notifyModel, '手机系统 消息推送成功');

            })->delay($this->queueLoop * self::QUEUE_DELAY_SECONDS);
        }
    }

    private int $queueLoop = 0; // 循环次数
    const QUEUE_DELAY_SECONDS = 60; // 每次循环延迟时间
    const QUEUE_LOOP_EACH_NUM = 30;  // 每次推送人数

    /**
     * @param SystemNotifyCenterModel $notifyModel
     * @throws GuzzleException
     */
    public function mobileBrandChannelPush(SystemNotifyCenterModel $notifyModel)
    {
        CommonPushBindModel::query()
                           ->whereIn("rmsUserId", $this->pushRmsUserIds)
                           ->where("status", CommonPushBindModel::STATUS_ON)
                           ->chunkById(
                               self::QUEUE_LOOP_EACH_NUM,
                               function (Collection $commonPushBindModelCollection) use ($notifyModel) {
                                   $commonPushBindModelCollection->groupBy("mobileBrand")->each(function (
                                       Collection $group,
                                       $mobileBrand
                                   ) use ($notifyModel) {
                                       $this->pushedRmsUserIds = array_merge(
                                           $this->pushedRmsUserIds,
                                           $group->pluck("rmsUserId")->toArray()
                                       );

                                       $path = attributeGet(jsonToArr($notifyModel->pushExtra, []), "path", "");

                                       $tempLoop = $this->queueLoop;

                                       // 厂商直连推送 - 异步处里
                                       dispatch(function () use ($mobileBrand, $group, $notifyModel, $path, $tempLoop) {

                                           Log::info("appPush dispatch {$tempLoop} AndroidDirect:{$mobileBrand} {$notifyModel->pushTitle}", $group->pluck("rmsUserId")->toArray());

                                           KfPushFactory::getInstance()->getFactory($mobileBrand)->multiPush(
                                               $group->pluck("regId")->toArray(),
                                               $notifyModel->pushTitle,
                                               empty(trim($notifyModel->summary)) ? $notifyModel->pushTitle : $notifyModel->summary,
                                               str_starts_with($path, "http") ?
                                                   "kuafoodmerchantapp://webView?url=" . urlencode($path) : $path,
                                               ["notifyCenterId" => $notifyModel->id]
                                           );
                                       })->delay($this->queueLoop * self::QUEUE_DELAY_SECONDS);

                                       $this->queueLoop++;
                                   });
                               }
                           );
    }

    /**
     * @param PushParam $pushParam
     * @param SystemNotifyCenterModel $notifyModel
     * @throws GuzzleException
     */
    public function jPush(PushParam $pushParam, SystemNotifyCenterModel $notifyModel)
    {
        $jpushRmsUserIds = array_diff($this->pushRmsUserIds, $this->pushedRmsUserIds);
        if ($jpushRmsUserIds) {

            collect($jpushRmsUserIds)
                ->chunk(self::QUEUE_LOOP_EACH_NUM)
                ->each(function ($userIds) use ($pushParam, $notifyModel) {

                    $tempLoop = $this->queueLoop;

                    dispatch(function () use ($pushParam, $notifyModel, $userIds, $tempLoop) {

                        Log::info("appPush dispatch {$tempLoop} jPush: {$notifyModel->pushTitle}", $userIds->toArray());

                        $pushParam->setUserIds($userIds->toArray());

                        // 是否有额外推送参数
                        $extra                         = json_decode($notifyModel->pushExtra, true);
                        $extra["kf"]["notifyCenterId"] = $notifyModel->id;
                        $extra["kf"]["path"]           = "";
                        if (is_array($extra) && count($extra)) {
                            if (isset($extra["path"]) && !empty($extra["path"])) {
                                $path                = $extra["path"];
                                $extra["kf"]["path"] = str_starts_with($path, "http") ?
                                    "kuafoodmerchantapp://webView?url=" . urlencode($path) : $path;
                            }
                            $pushParam->setExtra($extra);
                        }

                        (new \Kuafu\AppPush\Push($pushParam))->doPush();
                    })->delay($this->queueLoop * self::QUEUE_DELAY_SECONDS);

                    $this->queueLoop++;
            });
        }
    }

    public function finishStatus($notifyModel)
    {
        // 判断是否只有手机推送
        if (empty($notifyModel->smsTemplate) && empty($notifyModel->summary)) {
            $notifyModel->status = SystemNotifyCenterModel::NOTIFY_STATUS_3;
            $notifyModel->save();
        }
    }
}
